﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace MonCorLib.Net.Service
{
    public class ClientSocketService : INetClientServiceable
    {
        private Socket client;
        private Thread thread;


        public ClientSocketService(string ip, int port)
        {
            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            client.Connect(new IPEndPoint(IPAddress.Parse(ip), port));

            thread = new Thread(new ThreadStart(Receive));
            thread.IsBackground = true;
            thread.Start(); 
        }

        public bool connect(string address)
        {
            throw new NotImplementedException();
        }

        public void Send(string msg)
        {
            try
            {
                if (client.Connected)
                {
                    byte[] data = Encoding.Default.GetBytes(msg);
                    this.SendData(data);
                }
                else
                {
                    //this.wnd.Add_MSG("메시지 전송 실패!");
                }
            }
            catch (Exception ex)
            {
                //this.wnd.Add_MSG(ex.Message);
            }
        }

        private void SendData(byte[] data)
        {
            try
            {
                int total = 0;
                int size = data.Length;
                int left_data = size;
                int send_data = 0;

                // 전송할 실제 데이터의 크기 전달
                byte[] data_size = new byte[4];
                data_size = BitConverter.GetBytes(size);
                send_data = this.client.Send(data_size);

                // 실제 데이터 전송
                while (total < size)
                {
                    send_data = this.client.Send(data, total, left_data, SocketFlags.None);
                    total += send_data;
                    left_data -= send_data;
                }
            }
            catch (Exception ex)
            {
                //this.wnd.Add_MSG(ex.Message);
            }
        }

        public void Receive()
        {
            try
            {
                while (client != null && client.Connected)
                {
                    byte[] data = this.ReceiveData();
                    string msg = Encoding.Default.GetString(data);

                    string[] token = msg.Split('\a');

                    switch (token[0])
                    {
                        case "STOC_MESSAGE_INFO": // 서버 방송 메시지 수신
                            //this.wnd.Add_MSG(token[1]);
                            break;

                        case "CTOC_CHAT_NEWTEXT_INFO":
                            //this.wnd.Add_Status("[" + client_ip + "] 님이 메시지를 입력합니다.");
                            break;

                        case "CTOC_CHAT_MESSAGE_INFO":
                            int index = msg.IndexOf('\a');
                            msg = msg.Substring(index + 1, msg.Length - index - 1);
                            //this.wnd.Add_MSG("[" + client_ip + "] 님의 말");
                            //this.wnd.Add_RichData(msg);
                            //this.wnd.Add_Status("마지막 메시지:" + DateTime.Now.ToString());
                            break;
                    }

                }
            }
            catch (Exception ex)
            {
                //this.wnd.Add_MSG(ex.Message);
            }
        }

        private byte[] ReceiveData()
        {
            try
            {
                int total = 0;
                int size = 0;
                int left_data = 0;
                int recv_data = 0;

                // 수신할 데이터 크기 알아내기   
                byte[] data_size = new byte[4];
                recv_data = this.client.Receive(data_size, 0, 4, SocketFlags.None);
                size = BitConverter.ToInt32(data_size, 0);
                left_data = size;

                byte[] data = new byte[size];
                // 서버에서 전송한 실제 데이터 수신
                while (total < size)
                {
                    recv_data = this.client.Receive(data, total, left_data, SocketFlags.None);
                    if (recv_data == 0) break;
                    total += recv_data;
                    left_data -= recv_data;
                }
                return data;
            }
            catch (Exception ex)
            {
                //this.wnd.Add_MSG(ex.Message);
                return null;
            }
        }

        public string getIP()
        {
            IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
            string myip = host.AddressList[0].ToString();
            return myip;
        }
    }
}
